using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class GameObjectPoolBase
{
    //  对象池的缓存池
    private readonly Queue<IPoolItem> _cachePool;         
    //  对象外部使用时的缓存池
    private readonly Queue<IPoolItem> _spawnPool;
    //  对象池是否能销毁
    private readonly bool _dontDestroy;
    //  缓存池初始容量
    private readonly int _initCapacity;
    //  缓存池最大容量
    private readonly int _maxCapacity;
    //  对象池销毁的延迟时间（当静默时间大于该时间则进行销毁判断）
    private readonly float _destroyDelay;
    //  对象池上一次回收全部对象的时间（真实时间）
    private float _lastRestoreRealTime;
    //  预制体路径
    private readonly string _prefabPath;
    //  对象池能否强制回收外面对象并重新使用
    private readonly bool _isForceRestore;
    //  对象池实例
    private GameObject _poolObj = null;
    
    /// <summary>
    /// 外部使用总数
    /// </summary>
    public int SpawnCount => _spawnPool.Count;

    /// <summary>
    /// 是否不销毁
    /// </summary>
    public bool DontDestroy => _dontDestroy;
    

    public GameObjectPoolBase(string prefabPath, bool dontDestroy, Transform parent,
        int initCapacity, int maxCapacity, float destroyDelay, bool isForceRestore)
    {
        string name = Path.GetFileNameWithoutExtension(prefabPath);
        _poolObj = new GameObject(name);
        _poolObj.transform.SetParent(parent);
        _prefabPath = prefabPath;
        _dontDestroy = dontDestroy;
        _initCapacity = initCapacity;
        _maxCapacity = maxCapacity;
        _destroyDelay = destroyDelay;
        _isForceRestore = isForceRestore;
        
        //  创建缓存池
        _cachePool = new Queue<IPoolItem>(_initCapacity);
        _spawnPool = new Queue<IPoolItem>();
    }
    
    /// <summary>
    /// 获取对象池对象
    /// </summary>
    /// <returns>IPoolItem对象</returns>
    public IPoolItem Spawn()
    {
        IPoolItem item = GetObjByQueue(_prefabPath);
        if (item == null)
        {
            item = CreateInstance();
        }

        return item;
    }

    /// <summary>
    /// 回收对象
    /// </summary>
    /// <param name="item"></param>
    public void UnSpawn(IPoolItem item)
    {
        if (_cachePool.Contains(item))
        {
            return;
        }
        item.IsPool = true;
        item.Target.transform.SetParent(_poolObj.transform);
        item.Target.SetActive(false);
        item.UnSpawn();
        _cachePool.Enqueue(item);
        _spawnPool.Dequeue();
    }

    /// <summary>
    /// 释放所有未使用对象
    /// </summary>
    private void ReleaseAllItem()
    {
        while (_cachePool.Count > 0)
        {
            var item = _cachePool.Dequeue();
            if (item != null)
            {
                GameObject.Destroy(item.Target);
            }
        }
    }

    /// <summary>
    /// 清理对象池
    /// </summary>
    public void Clear()
    {
        if (SpawnCount > 0)
        {
            LogUtility.LogError(Path.GetFileNameWithoutExtension(_prefabPath) + "正在外部使用，无法清理该对象池");
        }
        else
        {
            ReleaseAllItem();
        }
    }

    /// <summary>
    /// 从对象池中获取对象
    /// </summary>
    /// <param name="prefabName"></param>
    /// <returns>IPoolItem对象</returns>
    public IPoolItem GetObjByQueue(string prefabName)
    {
        IPoolItem poolItem = null;
        if (_cachePool.Count == 0)
        {
            if (_isForceRestore)
            {
                //  强制回收外部最先使用的对象
                poolItem = _spawnPool.Dequeue();
            }
            else
            {
                return null;
            }
        }
        else
        {
            poolItem = _cachePool.Dequeue();
        }
        try
        {   
            //  尝试获取item的gameobject
            var target = poolItem.Target;
        }
        catch
        {
            //  未获取到gameobject，打印日志
            LogUtility.LogError(Path.GetFileNameWithoutExtension(prefabName) + " poolItem is null");
            return null;
        }
        _spawnPool.Enqueue(poolItem);
        return poolItem;
    }

    private IPoolItem CreateInstance()
    {
        // TODO 资源管理类完成后继续
        return null;
    }
    

    /// <summary>
    /// 判断静默时间内是否可以自动销毁对象池
    /// </summary>
    public bool CanAutoDestroy()
    {
        if (_dontDestroy)
        {
            return false;
        }

        if (_destroyDelay < 0)
        {
            return false;
        }
        
        // 当之前回收过对象并且外部没有引用该对象池中的对象
        if (_lastRestoreRealTime > 0 && SpawnCount <= 0)
        {
            // 超过静默时间，则可以自动销毁
            return (Time.realtimeSinceStartup - _lastRestoreRealTime) > _destroyDelay;
        }
        return false;
    }
}
